#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
 
typedef unsigned char  	BYTE;
typedef unsigned short  WORD;
typedef unsigned int  	DWORD;
typedef int  		LONG;
 
#define ALIGN_UP(x, a)           ( ( ((x) + ((a) - 1) ) / a ) * a )

#define BITS_PER_PIXCEL 24
#define FORMAT_RGBA 4
#define FORMAT_RGB  3
 
/** must needed. pack */
#pragma pack(1)
 
typedef struct
{
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BMP_FILE_HEADER;
 
typedef struct{
    DWORD      biSize;
    LONG       biWidth;
    LONG       biHeight;
    WORD       biPlanes;
    WORD       biBitCount;
    DWORD      biCompression;
    DWORD      biSizeImage;
    LONG       biXPelsPerMeter;
    LONG       biYPelsPerMeter;
    DWORD      biClrUsed;
    DWORD      biClrImportant;
} BMP_INFO_HEADER;
 
#pragma pack()

int bgr_planner2bgr_packed(int width, int height, unsigned char * img_data, unsigned char *img_data_conv)
{
	printf("bgr_planner2bgr_packed is comming !\n");
	int channel = 3;
	//int width = scale_frame->stVFrame.u32Stride[0];
	//int height = scale_frame->stVFrame.u32Height;
	//unsigned char * img_data = (HI_U8 *)(HI_UL)scale_frame->stVFrame.u64VirAddr[0];
	//unsigned char *img_data_conv = NULL;
	//img_data_conv = (unsigned char *)malloc(sizeof(unsigned char) * width * height * channel);
	int stride = ALIGN_UP(width, 16);
	for (int k = 0; k < channel; k++)
			for (int i = 0; i < height; i++)
				for (int j = 0; j < width; j++)
					img_data_conv[channel * (i * width + j) + k] = img_data[k * height * stride + i * stride + j]; ///* 如果想输出 rgb ,把等号左边里的 k ---> 2 - k */
	
	return 1;
	
}

 
int rgbaToBmpFile(int Width, int Height, unsigned char *img_data)
{
	printf("rgbaToBmpFile is comming !\n");
	BMP_FILE_HEADER bmpHeader;
    BMP_INFO_HEADER bmpInfo;
 
    FILE* fp         = NULL;
    char* pBmpSource = NULL;
    char* pBmpData   = NULL;
 	char *pFileName = "yvu_image/test.bmp";
    int i = 0, j = 0;
	//int Width = scale_frame->stVFrame.u32Width;
	//int Height = scale_frame->stVFrame.u32Height;
	int channel = 3;
 	unsigned char *pRgbaData = NULL;
	unsigned char *RgbaData = NULL;
	pRgbaData = (unsigned char *)malloc(sizeof(unsigned char) * Width * Height * channel);
	RgbaData = pRgbaData;
	//unsigned char pRgbaData[Width * Height * channel] = {0};
	int ret = bgr_planner2bgr_packed(Width, Height, img_data, pRgbaData);
	printf("bgr_planner2bgr_packed is over !\n");
    //4 bytes pack. must be 4 times per line。
    int bytesPerLine = (Width * BITS_PER_PIXCEL + 31) / 32 * 4; // 31是保证32位对齐的填充值，这样输出的值肯定是32的倍数,乘上4是因为除了一个32位（4字节）
    int pixcelBytes  = bytesPerLine * Height;
 
    bmpHeader.bfType        = 0x4D42;
    bmpHeader.bfReserved1   = 0;
    bmpHeader.bfReserved2   = 0;
    bmpHeader.bfOffBits     = sizeof(BMP_FILE_HEADER) + sizeof(BMP_INFO_HEADER);
    bmpHeader.bfSize        = bmpHeader.bfOffBits     + pixcelBytes;
  
    bmpInfo.biSize          = sizeof(BMP_INFO_HEADER);
    bmpInfo.biWidth         = Width;
    /** 这样图片才不会倒置 */
    bmpInfo.biHeight        = -Height; 
    bmpInfo.biPlanes        = 1;
    bmpInfo.biBitCount      = BITS_PER_PIXCEL;
    bmpInfo.biCompression   = 0;
    bmpInfo.biSizeImage     = pixcelBytes;
    bmpInfo.biXPelsPerMeter = 100;
    bmpInfo.biYPelsPerMeter = 100;
    bmpInfo.biClrUsed       = 0;
    bmpInfo.biClrImportant  = 0;
 
 
    /** convert in memort, then write to file. */
    pBmpSource = malloc(pixcelBytes);
    if (!pBmpSource)
    {
        return -1;
    }
 
    /** open file */
    fp = fopen(pFileName, "wb+");
    if (!fp)
    {
        return -1;
    }
 	printf("pFileName = %s\n", pFileName);
    fwrite(&bmpHeader, sizeof(BMP_FILE_HEADER), 1, fp); // 写入文件头
    fwrite(&bmpInfo,   sizeof(BMP_INFO_HEADER), 1, fp);
	//printf("here 0.5\n");
    /** Here you should consider color format. RGBA ? RGB? BGR?
        Param format is RGBA, format for file is BGR */
    pBmpData = pBmpSource;
	//printf("here 1\n");
    for (i=0; i<Height; i++)
    {
        for (j=0; j<Width; j++) // bmp 也是 bgr 排列
        {
           pBmpData[0] = pRgbaData[0];
           pBmpData[1] = pRgbaData[1];
           pBmpData[2] = pRgbaData[2];
	       //pRgbaData += FORMAT_RGBA;
		   pRgbaData += FORMAT_RGB;
           pBmpData  += FORMAT_RGB;
        }
        //pack for 4 bytes
        pBmpData +=(bytesPerLine - Width * 3); // 跳过每行里填充的数据
    }
    fwrite(pBmpSource, pixcelBytes, 1, fp);
 	//printf("here 2\n");
    /** close and release。 */
    fclose(fp);  
    free(pBmpSource);
	//printf("here 3\n");
 	free(RgbaData);
	printf("rgbaToBmpFile is over \n");
    return 0;
}

